package com.macro.mall.common.aop;


import cn.hutool.json.JSONUtil;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.api.ResultCode;
import com.macro.mall.common.util.AESUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.macro.mall.common.annotation.ResponseEncrypt;

/**
 * @ClassName :  ResponseEncryptAOP
 * @Description :  传输加密模块AOP，对接口的出参进行加密，注意顺序不能乱，
 * 此AOP必须第一个执行，因为最先执行的最后结束，这样才能在各个AOP都执行完毕之后完成最后的加密
 * @Author :  AD
 */

@Order(value = 0)
@Aspect
@Component
public class ResponseEncryptAop {

    @Pointcut("@annotation(com.macro.mall.common.annotation.ResponseEncrypt)")
    public void point() {
    }

    /**
     * 环绕增强，加密出参
     */
    @Around(value = "point()  &&  @annotation(responseEncrypt)")
    public Object aroundEncrypt(ProceedingJoinPoint joinPoint, ResponseEncrypt responseEncrypt) throws Throwable {
        //返回的结合
        Object returnValue = null;
        //从上下文中提取
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

        //业务执行返回结果
        returnValue = joinPoint.proceed();
        System.out.println("returnValue.toString()  =  " + JSONUtil.toJsonStr(returnValue));

        if (returnValue instanceof CommonResult){
            Object data = ((CommonResult<?>) returnValue).getData();
            //获取到前端传递过来的AES密钥，然后对响应数据进行AES加密操作
            String aesKey = request.getParameterMap().get("aesKey")[0];
            System.out.println("aesKey  =  " + aesKey);
            String encryptToBase64Data = AESUtil.encryptWithKeyBase64(JSONUtil.toJsonStr(data), aesKey);
            ((CommonResult<String>) returnValue).setData(encryptToBase64Data);

        }


       // AESUtil.decryptFromBase64(returnValue,aesKey);
        return returnValue;
    }
}